// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Engine/DataAsset.h"
#include "GameplayTagContainer.h"

#include "LyraAbilityTagRelationshipMapping.generated.h"

class UObject;

/** Struct that defines the relationship between different ability tags */

/** 定义不同能力标签之间关系的结构体。 */
USTRUCT()
struct FLyraAbilityTagRelationship
{
	GENERATED_BODY()

	/** The tag that this container relationship is about. Single tag, but abilities can have multiple of these */

	/** 这个容器关系所相关的标签。单个标签，但是能力能够有多个标签。 */
	/**
	 * NOTE: Categories，一种猜想，但感觉就是这样的，Categories过滤Tag，也就是说这个变量只接受Gameplay.Action标签的自身及子标签，其他的标签不接受。
	 * NOTE: 能力标签。
	 */
	UPROPERTY(EditAnywhere, Category = Ability, meta = (Categories = "Gameplay.Action"))
	FGameplayTag AbilityTag;

	/** The other ability tags that will be blocked by any ability using this tag */

	/** 其他能力标签将会被任意使用这个标签的能力阻塞。 */

	/**
	 * NOTE: 阻塞其他能力的标签。
	 */
	UPROPERTY(EditAnywhere, Category = Ability)
	FGameplayTagContainer AbilityTagsToBlock;

	/** The other ability tags that will be canceled by any ability using this tag */

	/**  其他能力标签将会被任意使用这个标签的能力取消。 */

	/**
	 * NOTE: 取消其他能力的标签。
	 */
	UPROPERTY(EditAnywhere, Category = Ability)
	FGameplayTagContainer AbilityTagsToCancel;

	/** If an ability has the tag, this is implicitly added to the activation required tags of the ability */

	/** 如果能力有这个标签，这个标签将会含蓄地添加激活请求这个能力的标签列表中。 */
	UPROPERTY(EditAnywhere, Category = Ability)
	FGameplayTagContainer ActivationRequiredTags;

	/** If an ability has the tag, this is implicitly added to the activation blocked tags of the ability */

	/** 如果能力有这个标签，这个标签将会含蓄地添加激活阻塞这个能力的标签列表中。 */
	UPROPERTY(EditAnywhere, Category = Ability)
	FGameplayTagContainer ActivationBlockedTags;
};


/** Mapping of how ability tags block or cancel other abilities */

/** 能力标签列表阻塞或取消其他能力的映射。 */
UCLASS()
class ULyraAbilityTagRelationshipMapping : public UDataAsset
{
	GENERATED_BODY()

private:
	/** The list of relationships between different gameplay tags (which ones block or cancel others) */

	/** 在不同游戏玩法标签的关系列表(那些标签会被阻塞或取消其他标签) */
	UPROPERTY(EditAnywhere, Category = Ability, meta=(TitleProperty="AbilityTag"))
	TArray<FLyraAbilityTagRelationship> AbilityTagRelationships;

public:
	/** Given a set of ability tags, parse the tag relationship and fill out tags to block and cancel */

	/** 给定能力标签的集合，解析标签的关系并且填充标签去阻塞或取消。 */
	void GetAbilityTagsToBlockAndCancel(const FGameplayTagContainer& AbilityTags, FGameplayTagContainer* OutTagsToBlock, FGameplayTagContainer* OutTagsToCancel) const;

	/** Given a set of ability tags, add additional required and blocking tags */

	/** 给定能力标签的集合，添加额外的请求或阻塞标签。 */
	void GetRequiredAndBlockedActivationTags(const FGameplayTagContainer& AbilityTags, FGameplayTagContainer* OutActivationRequired, FGameplayTagContainer* OutActivationBlocked) const;

	/** Returns true if the specified ability tags are canceled by the passed in action tag */

	/** 如果这个特定能力标签凭借行为标签被取消则返回True。 */
	bool IsAbilityCancelledByTag(const FGameplayTagContainer& AbilityTags, const FGameplayTag& ActionTag) const;
};
